//
// Created by pzw on 24-3-19.
//

#include "ItrAdapter.h"

void ItrAdapter::reverse_itr_test(std::vector<int> &v, std::list<char> &lst) {
    v.rbegin()[3] = 7;                           // 正确：随即访问迭代器
#if 0
    lst.rbegin()[3] = '4';                       // 错误：双向迭代器不支持[]
#endif
    *(std::next(lst.rbegin(), 3)) = '4';    // 正确！
}

template<typename C, typename Val>
auto ItrAdapter::find_last(C &c, Val v) -> decltype(c.begin()) {
    using namespace std;
    auto ri = find(c.rbegin(), c.rend(), v);
    if (ri == c.rend()) {
        return c.end();
    }
    return prev(ri.base());
}

template<typename C, typename Val>
auto ItrAdapter::find_last2(C &c, Val v) -> decltype(c.begin()) {
    for (auto p = c.rbegin(); p != c.rend(); ++p) {
        if (*p == v) {
            return --p.base();
        }
    }
    return c.end();
}

template<typename C, typename Val>
auto ItrAdapter::find_last3(C &c, Val v) -> decltype(c.begin()) {
    for (auto p = c.end(); p != c.begin();) {
        if (*--p == v) {
            return p;
        }
    }
    return c.end();
}

void ItrAdapter::std_insert_itr(
        std::vector<int> &v_insert_ptr,
        std::vector<int> &v_back_insert,
        std::list<int> &lst_front_insert) {
    using namespace std;
    fill_n(inserter(v_insert_ptr, v_insert_ptr.begin() + 3), 200, 9);
    /* 将200个7添加(插入)到vi的末尾 */
    fill_n(back_inserter(v_back_insert), 200, 7);
    fill_n(front_inserter(lst_front_insert), 200, 8);
}

void ItrAdapter::std_make_move_itr() {
    using namespace std;
    vector<string> read_strings(istream &);
    auto vs = read_strings(cin);

    vector<string> vs2;
    copy(vs.begin(), vs.end(), back_inserter(vs2));

    vector<string> vs3;
#if 0 // 不知道那个创造C++那个傻逼，为什么写这个代码，编译不过
    copy(vs2.begin(), vs2.end(), make_move_iterator(back_inserter(vs3)));
#endif
    /* 这个才是make_move_iterator的正确写法 */
    copy(
            make_move_iterator(vs2.begin()),
            make_move_iterator(vs2.end()),
            back_inserter(vs3)
    );
}

std::vector<std::string> read_strings(std::istream &cin) {
    return {"", "", "", ""};
}

int ItrAdapter_main() {
    std::vector<int> vs{0, 1, 2, 3, 4, 5, 6, 7};
    std::list<char> lst{'7', '6', '5', '4', '3', '2', '1', '0'};
    ItrAdapter::reverse_itr_test(vs, lst);

    auto vs3 = ItrAdapter::find_last(vs, 3);
    auto lst6 = ItrAdapter::find_last2(lst, '6');
    auto lst7 = ItrAdapter::find_last3(lst, '7');
    std::cout << "ItrAdapter_main: vs3 = " << *vs3
              << ", lst6 = " << *lst6
              << ", lst7 = " << *lst7 << std::endl;

    std::vector<int> ptr_insert_vs{0, 1, 2, 3, 4, 5, 6, 7};
    std::vector<int> back_insert_vs{0, 1, 2, 3, 4, 5, 6, 7};
    std::list<int> front_insert_lst{0, 1, 2, 3, 4, 5, 6, 7};
    ItrAdapter::std_insert_itr(ptr_insert_vs, back_insert_vs, front_insert_lst);
    std::cout << "ItrAdapter_main: ptr_insert_vs = ";
    for (auto it = ptr_insert_vs.begin(); it != ptr_insert_vs.end(); ++it) {
        std::cout << *it << ", ";
    }
    std::cout << std::endl;
    std::cout << "ItrAdapter_main: back_insert_vs = ";
    for (auto it = back_insert_vs.begin(); it != back_insert_vs.end(); ++it) {
        std::cout << *it << ", ";
    }
    std::cout << std::endl;
    std::cout << "ItrAdapter_main: front_insert_lst = ";
    for (auto it = front_insert_lst.begin(); it != front_insert_lst.end(); ++it) {
        std::cout << *it << ", ";
    }
    std::cout << std::endl;

    ItrAdapter::std_make_move_itr();

    return 0;
}